///@file Element.h
///@brief Declaration of the class representing a mesh finite element
///@author Arnaud Duval
///@version 0.0
///@date 2010/02/26


#ifndef ELEMENT_H
#define ELEMENT_H

#include <assert.h>
#include <iostream>
#include <list>

#include "Node.h"
#include "Material.h"

#include "../../mathobject/include/mathobject.h"

///@class Element
///@brief class defining a mesh finite element
///A node is defined by its coordinates and its reference
class Element
{
	private:
	protected:
		///@brief List of pointers to the nodes of the element
		std::list<Node*> nodes;
		///@brief Pointer to the assigned material
		Material* mat;
		///@brief Reference of element
		std::string reference;
		///@brief Type of element
		std::string type;
		///@brief Number of Gauss points
		unsigned int nbGauss;
	public:
		///@brief Default constructor
		Element();
		///@brief Destructor
		virtual ~Element();
		///@brief Direct access to reference of element
		std::string& Reference();
		///@brief Direct acces to type of element
		std::string& Type();
		///@brief Set material
		void SetMaterial(Material*);
		///@brief Update specific values of element
		virtual void Update();
		///@brief Compute nodal residual from nodal DOF increment
		virtual void Equilibrate(const Vector&, Vector&, Matrix&);
        ///@brief Compute nodal residual from nodal DOF increment with similarities to Abaqus UEL
        virtual void UEL(Vector&, Matrix&, Vector&, const Vector&, const Vector&);
		///@brief Compute displacements interpolation matrix at a given intagration point
		virtual Matrix N(unsigned int);
		///@brief Compute strain matrix operator at a given intagretio point
		virtual Matrix B(unsigned int);

		///@brief Overload of operator <<
		friend std::ostream& operator<<(std::ostream&, Element&);

};

#endif